package com.ubing.boot.notesforjava.utils;

import cn.hutool.core.util.DesensitizedUtil;
import com.ubing.boot.notesforjava.annotation.Sensitive;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class SensitiveUtils {

    public static void isSensitive(Object obj){
        Field[] fields = obj.getClass().getDeclaredFields();
        try {
        for (Field field : fields) {
            Sensitive sensitive = field.getAnnotation(Sensitive.class);
            if(sensitive!=null){
                field.setAccessible(true);
                field.set(obj, DesensitizedUtil.desensitized(String.valueOf(field.get(obj)),sensitive.value()));
                }
            }
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void isSensitive(List<?> list){
        if(list.size()==0) return;
        Object o = list.get(0);
        Field[] fields = o.getClass().getDeclaredFields();
        List<Field> sensitiveFields = Arrays.stream(fields).filter(item -> item.getAnnotation(Sensitive.class) != null).collect(Collectors.toList());
        try {
            for (Object obj : list) {
                for (Field sensitiveField : sensitiveFields) {
                    sensitiveField.setAccessible(true);
                    sensitiveField.set(obj, DesensitizedUtil.desensitized(String.valueOf(sensitiveField.get(obj)), sensitiveField.getAnnotation(Sensitive.class).value()));
                }
            }
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Deprecated
    public static void isSensitive(@NotNull Class<?> clazz){
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            Sensitive annotation = field.getAnnotation(Sensitive.class);
            if(annotation!=null){
                /**
                 * public static InvocationHandler getInvocationHandler(Object proxy)
                 * 参数：
                 * proxy - 代理实例返回的调用处理程序。
                 * 返回值 - 代理实例的调用处理程序。
                 * 异常 - IllegalArgumentException - 如果参数不是代理实例则抛出此异常。
                 */
                InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);// annotation为代理类，
                try {
                    Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
                    memberValues.setAccessible(true);
                    Map map = (Map) memberValues.get(invocationHandler);
                    map.put("isSensitive",true);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    @Deprecated
    public static void isNoSensitive(Class<?> clazz){
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            Sensitive annotation = field.getAnnotation(Sensitive.class);
            if(annotation!=null){
                /**
                 * public static InvocationHandler getInvocationHandler(Object proxy)
                 * 参数：
                 * proxy - 代理实例返回的调用处理程序。
                 * 返回值 - 代理实例的调用处理程序。
                 * 异常 - IllegalArgumentException - 如果参数不是代理实例则抛出此异常。
                 */
                InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);// annotation为代理类，
                try {
                    Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
                    memberValues.setAccessible(true);
                    Map map = (Map) memberValues.get(invocationHandler);
                    map.put("isSensitive",false);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}
